import socket
import sys
import time
import logging
class Server(object):
    def __init__(self):
        self.logger = logging.getLogger('ServerLog')
        self.set_Logger()
        self.host=socket.gethostbyname(socket.gethostname())
        # self.host = 'localhost'
        self.port = 5000
        self.addr = (self.host, self.port)
        self.listenfd = socket.socket() #监听描述符
        self.buffer = 1024
        self.socket_list = [] #select函数的参数
        self.user_dict={} #key:客户端的ADDR value:客户自定义的名字
        self.user_list=[] #记录客户自定义的名字
        self.set_listenfd()


    def set_Logger(self):
        self.logger.setLevel(logging.DEBUG)

        hdr1=logging.StreamHandler()
        hdr2=logging.FileHandler(filename="server.log",mode="w")
        
        formatter=logging.Formatter("%(asctime)s - %(levelname)s : %(message)s")
        hdr1.setFormatter(formatter)
        hdr2.setFormatter(formatter)

        self.logger.addHandler(hdr1)
        self.logger.addHandler(hdr2)


    # 监视描述符的设置
    def set_listenfd(self):
        self.listenfd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            self.listenfd.bind(self.addr)
        except socket.error as e:
            self.logger.error("Bind failed : {}".format(e))
            exit(0)
        try:
            self.listenfd.listen(5)
        except socket.error as e:
            self.logger.error("Listen failed : {}".format(e))
            exit(0)
        self.socket_list.append(self.listenfd)
        self.logger.info("Server start running")

    # 将消息发送给所有客户端
    def broadcast(self, sender, msg):
        if  type(msg) == bytes :
            msg=msg.decode()
        msg = "{} \n {} \n".format(time.ctime(), msg)
        for sendSocket in self.socket_list:
            if sendSocket != self.listenfd and sendSocket != sender:
                try:
                    sendSocket.sendall(msg.encode())
                except socket.error as e:
                    self.logger.error("Broadcast failed : {}".format(e))
                    sendSocket.close()
                    self.socket_list.remove(sendSocket)

    # 有新客户连接时的操作
    def new_member(self,conn,addr):
        self.socket_list.append(conn)
        conn.sendall(b"Welcome to chatroom\nSet your name...")
        try :
            user_name=conn.recv(self.buffer).decode()
            self.user_dict[conn]=user_name
            self.user_list.append(user_name)
            self.broadcast(conn,"{} entered room\n".format(user_name))
            self.logger.info("Connnecting with {} , name is {}".format(addr,user_name))
            conn.sendall(("Some people in this chatroom,they are {} \n".format(self.user_list)).encode())
        except Exception as e:
            self.logger.error(e)


    #客户端断开之后的操作
    def leave(self,conn):
        user_name = self.user_dict[conn]
        leave_msg="Client {} is offline \n".format(self.user_dict[conn])
        self.broadcast(conn, leave_msg)
        self.logger.info(leave_msg)
        self.socket_list.remove(conn)
        self.user_list.remove(user_name)
        del self.user_dict[conn]
        conn.close()


    #接收来自客户端消息的操作
    def communicateWith(self,conn):
        try:
            recvData=conn.recv(self.buffer)
        except socket.error as e :
            self.leave(conn)
            return False
        msg = "< {} >  {} \n{}".format(self.user_dict[conn], time.ctime(), recvData.decode())
        self.broadcast(conn,msg)
        return True


if __name__ == '__main__':
    pass